#include "Wheel.h"
#include "application.h"
#include "Util.h"
#include "Camera.h"
#include <OgreManualObject.h>
#include <OgreAnimationState.h>
#include <OgreEntity.h>
using namespace Ogre;

Wheel::Wheel() : Object("wheel")
{
	writelog ("Creating entity for wheel "+mName);
    mEntity = gSceneMgr->createEntity (mName,"wheel.mesh");
	mHamsterEntity = gSceneMgr->createEntity (mName+"_hamster","hamster.mesh");
	mWheelNode = mNode->createChildSceneNode (mName+"_wheel_node");
	mHamsterNode = mNode->createChildSceneNode (mName+"_hamster_node");
	
	mSightNode = mMainCamera->createChildSceneNode (mName + "_target", Ogre::Vector3 (0,0,15));
	mCameraPosition = mMainCamera->createChildSceneNode (mName + "_camera", Ogre::Vector3 (0,0.5,-1)); // change camera coordinates here
    
    mWheelNode->attachObject ((MovableObject*) mEntity);
	mHamsterNode->attachObject ((MovableObject*) mHamsterEntity);
	mHamsterNode->setScale (0.6,0.6,0.6);
	mHamsterNode->setPosition (0,-2,0);

	mAniState=mHamsterEntity->getAnimationState("Action");
	mAniState->setEnabled(1);

	mNode->setScale (0.05,0.05,0.05);	
	
	Ogre::ManualObject* mo=gSceneMgr->createManualObject("aoeu");
	mo->begin("wireframe_material", RenderOperation::OT_LINE_LIST);
	
	for (int i=0;i<50;i++)
	{
		mo->position(0,0,0);
		mo->position(sin(i*2*3.1515/50),0,cos(i*2*3.1515/50));
	}
	mo->end();
	mo->setRenderQueueGroup(70);

	//mNode->attachObject(mo);

	writelog("Creating Physics object representing wheel "+mName);
	
	// Create physics object
	NxActorDesc actorDesc;
	NxBodyDesc bodyDesc;
	NxSphereShapeDesc d[20];
	NxSphereShapeDesc e[20];
	NxSphereShapeDesc f[20];

	NxMat33 mat;
	float radius=0.15;
	float radius2=0.06;

	for (int i=0;i<20;i++)
	{
		d[i].localPose.t=NxVec3(sin(i*2*3.1415/20)*radius,0,cos(i*2*3.1415/20)*radius);
		d[i].radius=0.07;
		//d[i].height=0.10;
		d[i].materialIndex=1;
		d[i].mass=8/20.0f;
		actorDesc.shapes.pushBack(&d[i]);
	}
	
	for (int i=0;i<20;i++)
	{
		e[i].localPose.t=NxVec3(sin(i*2*3.1415/20)*radius2,-0.3,cos(i*2*3.1415/20)*radius2);
		e[i].radius=0.03;
		//d[i].height=0.10;
		e[i].materialIndex=1;
		e[i].mass=6/20.0f;
		actorDesc.shapes.pushBack(&e[i]);
	}

	for (int i=0;i<20;i++)
	{
		f[i].localPose.t=NxVec3(sin(i*2*3.1415/20)*radius2,0.3,cos(i*2*3.1415/20)*radius2);
		f[i].radius=0.03;
		//d[i].height=0.10;
		f[i].materialIndex=1;
		f[i].mass=6/20.0f;
		actorDesc.shapes.pushBack(&f[i]);
	}
/*	
	//d1.dimensions.set(0.5f,0.5f,0.5f); ;
	d1.radius=0.6;
	
	d1.height=1.1;
	d1.materialIndex=1;
	d1.localPose.t = NxVec3(0, 0, 0);
	//d1.mass = 5; 
*/
	
	actorDesc.body			= &bodyDesc;
	actorDesc.density		= 1.0f;
	actorDesc.globalPose.t	= NxVec3(0,0,0); 
	assert(actorDesc.isValid());
	mActor = gScene->createActor(actorDesc);
	mActor->setGlobalPosition(NxVec3(10,5,10));

	//gCamera->setTarget(this);
}

void Wheel::update(float k)
{
	mAniState->addTime(k*2);

	NxVec3 pos=mActor->getGlobalPosition();
	NxQuat quat=mActor->getGlobalOrientationQuat();
	
	Quaternion q;
	q.x=quat.x; q.y=quat.y; q.z=quat.z; q.w=quat.w;

	mNode->setPosition(pos.x,pos.y,pos.z);	
	mMainCamera->setPosition (pos.x, pos.y, pos.z);

	Vector3 src = mMainCamera->_getDerivedOrientation () * Vector3::UNIT_X;
	src.y = 0;
	src.normalise ();
	Vector3 dest = mWheelNode->_getDerivedOrientation () * Vector3::UNIT_X;
	dest.y = 0;
	dest.normalise ();	
	Quaternion rot = src.getRotationTo (dest);
	rot.x = 0;
	rot.z = 0;
	rot.normalise ();

	mMainCamera->rotate (rot);
	NxReal angle;
	NxVec3 axis;
	quat.getAngleAxis(angle,axis);
	mWheelNode->setOrientation(quat.w,quat.x,quat.y,quat.z);
	Matrix3 krot;
	mWheelNode->getOrientation().ToRotationMatrix(krot);
	mWheelNode->rotate(Vector3(0,0,1),Degree(90));
	
	mHamsterNode->resetOrientation();

	mHamsterNode->setInheritOrientation(0);

	
	//mHamsterNode->setOrientation(quat.w,quat.x,quat.y,quat.z);
	//mHamsterNode->setFixedYawAxis(1);
	//mHamsterNode->yaw(r);
	mHamsterNode->setDirection(krot.GetColumn(1)); // f*in finally!
	mHamsterNode->yaw(Degree(90));
	mHamsterNode->roll(Degree(90));

	//mHamsterNode->resetOrientation();

	//mHamsterNode->setOrientation(mWheelNode->getOrientation().Inverse());
	//mHamsterNode->rotate(Vector3(0,0,1),Degree(90));
	//mHamsterNode->rotate(Vector3(1,0,0),Degree(90));
	//mHamsterNode->setDirection(0,0,-1,Ogre::Node::TS_WORLD);
	//mHamsterNode->yaw(q.getRoll());
	//gCamera->setPosition(pos.x,pos.y + 5, pos.z + 5);
	mHamsterNode->yaw(Degree(90));
}